package org.xx.armory.swing.components.verifiers;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.DOTALL;
import static java.util.regex.Pattern.UNICODE_CASE;
import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.xx.armory.commons.Validators.greaterThanOrEqual;

/**
 * 文本的验证器。也可以用于校验密码。
 * <p>此验证器进行必填校验，最大长度校验和正则表达式匹配校验。</p>
 */
public class SimpleTextVerifier
        implements TextVerifier {
    @SuppressWarnings("unused")
    private final Logger logger = LoggerFactory.getLogger(SimpleTextVerifier.class);

    private final boolean required;
    private final int maxLength;
    private final Pattern pattern;

    /**
     * 构造输入文本校验器。
     *
     * <p>不校验最大长度和正则表达式样式。</p>
     *
     * @param required
     *         是否必填。
     */
    public SimpleTextVerifier(
            boolean required
    ) {
        this(required, -1, "");
    }

    /**
     * 构造输入文本校验器。
     *
     * @param required
     *         是否必填。
     * @param maxLength
     *         最大长度。
     * @param pattern
     *         正则表达式样式。
     */
    public SimpleTextVerifier(
            boolean required,
            int maxLength,
            String pattern
    ) {
        this.required = required;
        this.maxLength = greaterThanOrEqual(maxLength, "maxLength", -1);
        pattern = trimToEmpty(pattern);
        if (!pattern.isEmpty()) {
            pattern = "^(" + pattern + ")$";
            this.pattern = Pattern.compile(pattern, DOTALL | UNICODE_CASE | UNICODE_CHARACTER_CLASS);
        } else {
            this.pattern = null;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public VerifiedStatus verify(
            JComponent input
    ) {
        final String text;
        if (input instanceof JFormattedTextField) {
            final Object obj = ((JFormattedTextField) input).getValue();
            text = obj != null ? obj.toString() : "";
        } else if (input instanceof JTextComponent) {
            text = ((JTextComponent) input).getText();
        } else if (input instanceof JComboBox) {
            final Object selectedItem = ((JComboBox) input).getSelectedItem();
            text = selectedItem != null ? selectedItem.toString() : "";
        } else {
            text = "";
        }

        if (this.required) {
            if (text.isEmpty()) {
                return VerifiedStatus.REQUIRED_ERROR;
            }
        }
        if (this.maxLength >= 0) {
            if (text.length() > maxLength) {
                return VerifiedStatus.FORMAT_ERROR;
            }
        }
        if (this.pattern != null) {
            final Matcher m = this.pattern.matcher(text);
            if (!m.find()) {
                return VerifiedStatus.FORMAT_ERROR;
            }
        }
        return VerifiedStatus.OK;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "text-verify{required=" + this.required + ",max-length=" + this.maxLength + ",pattern=" + this.pattern + "}";
    }
}
